
#include "task.hpp"

using namespace std;

const int gnum = 5;

Task t;

struct EndPoint
{
    int child_id;
    int pipefd;
    EndPoint(int id, int fd)
        : child_id(id), pipefd(fd)
    {
    }
};

void WriteCommand()
{
    while (true)
    {
        int command = 0;
        int n = read(0, &command, sizeof(int));
        if (n == sizeof(int))
        {
            // 读取成功
            t.Execute(command);
        }
        else if (n == 0)
        {
            // 读到文件的结尾
            break;
        }
        else
        {
            cout << "任务读取失败!" << endl;
            break;
        }
    }
}
void CreatProcess(vector<EndPoint> &arr)
{
    // 父进程写，子进程读
    for (int i = 0; i < gnum; ++i)
    {
        // 1.创建管道
        int pipefd[2] = {0};
        int n = pipe(pipefd);
        if (n == -1)
        {
            perror("pipe fail::");
            exit(-1);
        }

        // 2.创建子进程
        pid_t id = fork();
        if (id == -1)
        {
            perror("fork() fail ::");
            exit(-1);
        }

        if (id == 0)
        {
            // 子进程,关闭写端
            close(pipefd[1]);

            // 重定向标准输入--也可以不做，给WriteCommand传参就行
            dup2(pipefd[0], 0);
            WriteCommand();

            close(pipefd[0]);
            exit(0);
        }

        // 父进程,关闭读端
        close(pipefd[0]);

        // 建立映射关闭，让对应的管道和对应的子进程建立联系
        arr.push_back(EndPoint(id, pipefd[1]));
    }
}

int main()
{
    vector<EndPoint> arr; // 用于保存对应的管道和对应的子进程间的联系
    // 创建框架
    CreatProcess(arr);

    //开始执行任务
    while(true)
    {
        //选择一个任务
        int command = COMMAND_LOG;
        //选择一个进程
        int index = rand()%arr.size();
        //执行任务
        write(arr[index].pipefd, &command, sizeof(int));
        sleep(1);
    }

    return 0;
}